use std::{
    collections::HashSet,
    net::IpAddr,
    sync::{Arc, RwLock},
    time::{SystemTime, UNIX_EPOCH},
};
use serde::{Deserialize, Serialize};
use crate::config::IpAuthConfig;

/// IP认证服务配置
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct IpAuthServiceConfig {
    pub enabled: bool,
    pub mode: String,
    pub whitelist: Vec<String>,
    pub blacklist: Vec<String>,
    pub max_requests_per_minute: u32,
}

/// IP认证模式转换
impl IpAuthServiceConfig {
    pub fn get_mode(&self) -> IpAuthMode {
        match self.mode.to_lowercase().as_str() {
            "whitelist" => IpAuthMode::Whitelist,
            "blacklist" => IpAuthMode::Blacklist,
            _ => IpAuthMode::Mixed,
        }
    }
}

/// IP认证模式
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum IpAuthMode {
    Whitelist, // 仅允许白名单IP
    Blacklist, // 仅阻止黑名单IP
    Mixed,     // 白名单优先，黑名单阻止
}

/// IP访问记录
#[derive(Debug, Clone)]
struct IpAccessRecord {
    ip: IpAddr,
    last_access: u64,
    request_count: u32,
}

/// IP认证服务
#[derive(Debug, Clone)]
pub struct IpAuthService {
    config: IpAuthServiceConfig,
    access_records: Arc<RwLock<Vec<IpAccessRecord>>>,
    whitelist: Arc<RwLock<HashSet<IpAddr>>>,
    blacklist: Arc<RwLock<HashSet<IpAddr>>>,
}

impl From<IpAuthConfig> for IpAuthServiceConfig {
    fn from(config: IpAuthConfig) -> Self {
        Self {
            enabled: config.enabled,
            mode: config.mode,
            whitelist: config.whitelist,
            blacklist: config.blacklist,
            max_requests_per_minute: config.max_requests_per_minute,
        }
    }
}

impl IpAuthService {
    pub fn new(config: IpAuthServiceConfig) -> Self {
        let whitelist: HashSet<IpAddr> = config.whitelist
            .iter()
            .filter_map(|ip_str| ip_str.parse().ok())
            .collect();
            
        let blacklist: HashSet<IpAddr> = config.blacklist
            .iter()
            .filter_map(|ip_str| ip_str.parse().ok())
            .collect();

        Self {
            config,
            access_records: Arc::new(RwLock::new(Vec::new())),
            whitelist: Arc::new(RwLock::new(whitelist)),
            blacklist: Arc::new(RwLock::new(blacklist)),
        }
    }

    /// 验证IP访问权限
    pub fn check_ip_access(&self, ip: &IpAddr) -> Result<(), String> {
        // 检查黑名单
        if self.blacklist.read().unwrap().contains(ip) {
            return Err(format!("IP {} is in blacklist", ip));
        }

        // 根据模式检查白名单
        match self.config.get_mode() {
            IpAuthMode::Whitelist => {
                if !self.whitelist.read().unwrap().contains(ip) {
                    return Err(format!("IP {} is not in whitelist", ip));
                }
            }
            IpAuthMode::Blacklist => {
                // 黑名单模式，只要不在黑名单就允许
                // 已经在上面检查过黑名单
            }
            IpAuthMode::Mixed => {
                // 混合模式：白名单优先，黑名单阻止
                if !self.whitelist.read().unwrap().contains(ip) {
                    return Err(format!("IP {} is not in whitelist", ip));
                }
            }
        }

        // 检查速率限制
        self.check_rate_limit(ip)?;

        Ok(())
    }

    /// 检查速率限制
    fn check_rate_limit(&self, ip: &IpAddr) -> Result<(), String> {
        let now = SystemTime::now()
            .duration_since(UNIX_EPOCH)
            .unwrap()
            .as_secs();
        
        let one_minute_ago = now - 60;
        
        let mut records = self.access_records.write().unwrap();
        
        // 清理过期记录
        records.retain(|record| record.last_access > one_minute_ago);
        
        // 查找或创建当前IP的记录
        let record = records
            .iter_mut()
            .find(|record| record.ip == *ip);
            
        match record {
            Some(record) => {
                record.request_count += 1;
                if record.request_count > self.config.max_requests_per_minute {
                    return Err(format!(
                        "Rate limit exceeded for IP {}. Max {} requests per minute", 
                        ip, self.config.max_requests_per_minute
                    ));
                }
                record.last_access = now;
            }
            None => {
                records.push(IpAccessRecord {
                    ip: *ip,
                    last_access: now,
                    request_count: 1,
                });
            }
        }

        Ok(())
    }

    /// 添加IP到白名单
    pub fn add_to_whitelist(&self, ip: &str) -> Result<(), String> {
        let ip_addr: IpAddr = ip.parse()
            .map_err(|_| format!("Invalid IP address: {}", ip))?;
            
        self.whitelist.write().unwrap().insert(ip_addr);
        Ok(())
    }

    /// 添加IP到黑名单
    pub fn add_to_blacklist(&self, ip: &str) -> Result<(), String> {
        let ip_addr: IpAddr = ip.parse()
            .map_err(|_| format!("Invalid IP address: {}", ip))?;
            
        self.blacklist.write().unwrap().insert(ip_addr);
        Ok(())
    }

    /// 从白名单移除IP
    pub fn remove_from_whitelist(&self, ip: &str) -> Result<(), String> {
        let ip_addr: IpAddr = ip.parse()
            .map_err(|_| format!("Invalid IP address: {}", ip))?;
            
        self.whitelist.write().unwrap().remove(&ip_addr);
        Ok(())
    }

    /// 从黑名单移除IP
    pub fn remove_from_blacklist(&self, ip: &str) -> Result<(), String> {
        let ip_addr: IpAddr = ip.parse()
            .map_err(|_| format!("Invalid IP address: {}", ip))?;
            
        self.blacklist.write().unwrap().remove(&ip_addr);
        Ok(())
    }

    /// 获取当前统计信息
    pub fn get_stats(&self) -> IpAuthStats {
        let records = self.access_records.read().unwrap();
        let whitelist = self.whitelist.read().unwrap();
        let blacklist = self.blacklist.read().unwrap();

        IpAuthStats {
            total_ips_tracked: records.len(),
            whitelist_count: whitelist.len(),
            blacklist_count: blacklist.len(),
            active_ips_last_minute: records.len(),
        }
    }
}

/// IP认证统计信息
#[derive(Debug, Clone, Serialize)]
pub struct IpAuthStats {
    pub total_ips_tracked: usize,
    pub whitelist_count: usize,
    pub blacklist_count: usize,
    pub active_ips_last_minute: usize,
}

/// 默认IP认证配置
impl Default for IpAuthServiceConfig {
    fn default() -> Self {
        Self {
            enabled: true,
            mode: "mixed".to_string(),
            whitelist: vec![
                "127.0.0.1".to_string(),
                "::1".to_string(),
                "192.168.1.0/24".to_string(),
            ],
            blacklist: vec![],
            max_requests_per_minute: 1000,
        }
    }
}